//
// Created by 123 on 2024/4/13.
//
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>

using namespace std;

sem_t offer1;
sem_t offer2;
sem_t offer3;
sem_t finish;

int sequence;

void* supplier_process(void* arg)
{
    cout << "supplier_process" << endl;
    while(1)
    {
        srand(time(0));
        sequence = rand() % 3;
        if(sequence == 0)
        {
            sem_post(&offer1);
            cout << "供应商提供烟草和纸" << endl;
        }
        else if (sequence == 1)
        {
            sem_post(&offer2);
            cout << "供应商提供烟草和胶水" << endl;
        }
        else
        {
            sem_post(&offer3);
            cout << "供应商提供纸和胶水" << endl;
        }
        cout << "供应商正在等待抽烟者完成吸烟" << endl;
        sem_wait(&finish);
    }
}

void* smoker_process_one(void* arg)
{
    cout << "smoker_process_one" << endl;
    while(1)
    {
        sem_wait(&offer3);
        cout << "第一个吸烟者拥有烟草，拿着供应商给的纸和胶水，卷烟吸烟" << endl;
        sleep(1);
        sem_post(&finish);
    }
}

void* smoker_process_two(void* arg)
{
    cout << "smoker_process_two" << endl;
    while(1)
    {
        sem_wait(&offer2);
        cout << "第二个吸烟者拥有纸张，拿着供应商给的烟草和胶水，卷烟吸烟" << endl;
        sleep(1);
        sem_post(&finish);
    }
}

void* smoker_process_three(void* arg)
{
    cout << "smoker_process_three" << endl;
    while(1)
    {
        sem_wait(&offer1);
        cout << "第三个吸烟者拥有胶水，拿着供应商给的纸和烟草，卷烟吸烟" << endl;
        sleep(1);
        sem_post(&finish);
    }
}

int main()
{
    sem_init(&offer1, 0, 0);
    sem_init(&offer2, 0, 0);
    sem_init(&offer3, 0, 0);
    sem_init(&finish, 0, 0);

    pthread_t supple;
    pthread_t smoker[3];

    pthread_create(&supple, nullptr, supplier_process, nullptr);

    pthread_create(&smoker[0], nullptr, smoker_process_one, nullptr);
    pthread_create(&smoker[1], nullptr, smoker_process_two, nullptr);
    pthread_create(&smoker[2], nullptr, smoker_process_three, nullptr);

    pthread_join(supple,nullptr);
    pthread_join(smoker[0],nullptr);
    pthread_join(smoker[1],nullptr);
    pthread_join(smoker[2],nullptr);

    return 0;
}

